import { AbstractSeeder } from '../abstract';
import { Prisma, PrismaClient } from '../../../src/generated/prisma';
import { MENU_DATA } from './menu.data';

export default class MenuSeed extends AbstractSeeder {
  name = 'Menu' as const;
  data = MENU_DATA;

  async exec(tx: Prisma.TransactionClient): Promise<void> {
    await Promise.all(
      this.data.map(m => {
          const { parent, ...menu } = m;
          const component = 'component' in m ? m.component : '#';
          return tx.menu.upsert({
            where: { name: m.name },
            update: {},
            create: {
              ...menu,
              component
            },
          });
        },
      ),
    );

    const menuMap = new Map(
      (await tx.menu.findMany({ select: { id: true, name: true } })).map(m => [ m.name, m.id ]),
    );

    const updates: Prisma.PrismaPromise<any>[] = [];
    for (const { name, parent } of this.data) {
      if (!parent) continue;
      const parentId = menuMap.get(parent);
      if (parentId) {
        updates.push(tx.menu.update({ where: { name }, data: { parentId: parentId } }));
      }
    }
    if (updates.length) await Promise.all(updates);
  }
}

if (require.main === module) {
  const prisma = new PrismaClient();
  new MenuSeed()
  .run(prisma)
  .catch(e => {
    console.error(e);
    process.exit(1);
  })
  .finally(() => prisma.$disconnect());
}

